English version Spanish version German version

Sessione 6: Aggiornare il Modello per permettere Spedizioni tra Impianti

Nella Sessione 5, avete incontrato il modello di un'industria di produzione che usava impianti multipli per produrre i propri prodotti. Quello che dovreste notare a proposito del modello è che, mentre ogni impianto potrebbe essere usato per produrre prodotti individualmente, tutte le vendite e gli inventari sono stati trattati collettivamente, come una fonte singola, per l'intera industria. Ora aggiornerete quel modello per far sì che ogni impianto venda i prodotti, e effettui individualmente l'inventario. Inoltre, al fine di compiere la richiesta nella maniera più efficiente, i prodotti possono essere spediti tra gli impianti come da bisogno.

Per aggiornare il modello avrete bisogno di includere due nuovi indici fittizi, toplant, e fromplant, che rappresenteranno la fonte e gli impianti di destinazione. Aggiornerete, inoltre, le variabili Inventory e Sales per includere l'indice plant, così che ogni impianto possa ora vendere i prodotti e mantenere ogni inventario indipendente dall'altro.


Nuovi Concetti in Questa Sessione

Modelli di Trasporto

I Modelli che permettono la spedizione tra diversi luoghi sono a volte chiamati modelli di trasporto o distribuzione. Tipicamente, nei modelli di trasporto, avete punti di partenza con una certa disponibilità, destinazioni con determinati requisiti, e avete bisogno di spedire i prodotti da questi punti di partenza a queste destinazioni. In alcuni casi, avete modelli di trasporto con livelli multipli.Per esmpio, ci possono essere carichi da impianti a depositi, e poi dai depositi a negozi di vendita al dettaglio.

Modelli di trasbordo

Un altro gruppo di modelli di distribuzione sono i modelli di transshipment(trasbordo). Questi modelli si presentano, tipicamente, quando si hanno posizioni multiple che producono entrambe beni e fungono, inoltre, come centri di richiesta. Fin qui non ci sono punti di partenza specifici o destinazioni, potete trasportare da qualsiasi posizione ad un 'altra.

Indici Fittizi

Gli Indici Fittizi sono utili quando si deve definire un vettore, che usa lo stesso indice più di una volta, come sottoscritto. Quando trasportate prodotti tra impianti avete bisogno di creare un vettore di variabile, che rappresenti quanto trasportare tra gli impianti. Dato che gli impianti di partenza e gli impianti di destinazione vengono dallo stesso set d'impianti, avete bisogno di due indici fittizi per gli impianti. Il primo indice fittizio deve rappresentare gli impianti di partenza, e il secondo deve rappresentare quelli di destinazione.

Uso delle Condizioni Where(Dove) su Variabili di Vettore

A volte, quando si lavora con variabili di vettore multi-dimensionale si incontrano casi in cui non tutti gli elementi del vettore sono validi, o hanno un significato.Per esempio, nel modelli di trasbordo avrebbe poco senso trasportare un prodotto da un certo impianto verso quello stesso. In questi casi, si può usare la condizione WHERE(DOVE) sulla variabile per rimuovere elementi non necessari.

Per esempio, in un modello di trasbordo potete eliminare la possibilità di trasportare alla stessa posizione definendo la variabile come segue:

     VARIABLES
        Ship[fromplant,toplant]
           WHERE (fromplant <> toplant);
    

In questo caso, la condizione (fromplant <> toplant) elimina tutti gli elementi di vettore, dove l'impianto di partenza è lo stesso di quello di destinazione.

In alcuni casi, gli elementi, che nono sono basati su valori degli indici, devono essere esclusi. Questi, dunque, devono essere basati su alcuni vettori di dati nel modello.Tipicamente, avete un vettore di costo che contiene quanto costa il trasporto tra impianti. Per questi impianti, se il trasporto non è possibile, potete introdurre un valore speciale per il costo, come zero, che venga usato per identificarli. Dunque, nella definizione della variabile, potete usare questo vettore di dati per escludere gli itinerari di spedizione che non sono possibili come segue:

     VARIABLES
        Ship[fromplant,toplant]
           WHERE (ShipCost[fromplant,toplant] > 0);
    

Vincoli d'Equilibrio d' Impianto

Quando si lavora con modelli di trasbordo si deve essere sicuri che la quantità dei prodotti spediti all'impianto, più quanto è prodotto e considerato nell' inventario sia uguale a quanto è trasportato dall'impianto, più quanto è venduto e rimesso nell'inventario . In breve, tutto ciò che va all' impianto deve essere uguale a tutto ciò che esce dall'impianto. Questio tipo di vincolo è tipicamente chiamato vincolo d'equilibrio d'impianto. Qui trovate un esempio di un semplice vincolo di equilibrio d' impianto:

     PlantBal[plant, product, month]:
         Produce + Inventory[month-1]
       + SUM(fromplant: Ship[fromplant, toplant:=plant])
     =
         Sales + Inventory
       + SUM(toplant: Ship[fromplant:=plant, toplant]);
    

Noterete che questo vincolo è simile al vincolo d'equilibrio dell'inventario che avete incontrato nella sessione precedente. L'unica differenza è che ora dovete tenere conto che stiamo trasportando a e da ogni impianto introducendo una sommatoria su ogni impianto per la variabile Ship (Imbarco).

Il compito dell'indice 'toplant:=plant', nella prima sommatoria, ci permette di specificare che il sottoscritto toplant dovrebbe prendere il valore del sottoscitto plant per il vincolo PlantBal. Questa sommatoria somma tutti i carichi da ogni impianto ad un particolare impianto in quel vincolo. In una maniera simile, l'assegnazione dell' indice 'fromplant:=plant', nella seconda sommatoria, specifica che il sottoscritto fromplant dovrebbe prendere il valore del sottoscritto plant.


Descrizione del problema: Sommatorie per Permettere Spedizioni tra Impianti

In questa sessione, verrà creato un nuovo modello in cui ogni impianto lavorerà, ora, come centro sparato di richiesta per i prodotti, e può inoltre mantenere l'inventario. Si userà il modello che avete creato nella Sessione 5, facendo le necessarie aggiunte e aggiornamenti su di esso.

Dato che ogni impianto può vendere i prodotti, noi ora abbiamo una differente richiesta per ogni impianto, come per ogni prodotto, e per ogni mese. La richiesta viene data nella tabella sottostante:

Questi dati possiedono tre dimensioni, impianti, prodotti e mesi. Nei modelli di programmazione lineare è abbastanza tipico avere dati con dimensioni multiple, possibilmente fino ad otto o più. Nella prossima Sessione, aggiorneremo i dati della richiesta così da includere una dimensione in più; le macchine , creando un vettore a quattro dimensioni.

La capacità dell'inventario è ora differente per ogni impianto. Abbiamo quattro valori di capienza d'inventario, uno per ogni impianto 800, 400, 500, e 400 rispettivamente.

Dato che ora abbiamo impianti multipli, ciascuno dei quali possa mantenere l'inventore, noi ora abbiamo differenti costi per ogni impianto, e per ogni prodotto. I nuovi valori di costo per l'inventario sono mostrati qui sotto:

Alla fine, dato che stiamo permettendo spedizioni tra gli impianti ci sono alcuni costi coinvolti per il trasporto di un prodotto, come mostrato nella tabella di sotto:

Come si può notare, non ci sono valori nella tabella dove l'impianto di partenza è lo stesso dell'impianto di destinazione. Questo perchè non esiste alcun beneficio nel trasportare indietro all' ipianto di partenza.


Formulazione del Modello in MPL

Elencata qui, di seguito, troverete l'intera formulazione del modello per Planning6. Le aggiunte al modello sono sottolineate in neretto al fine di rendere più semplice la lettura dei cambiamenti dal modello della Sessione 5.

     TITLE
         Production_Planning6;

     INDEX
         product   := (A1, A2, A3);
         month     := (Jan, Feb, Mar, Apr);
         plant     := (p1, p2, p3, p4);
         fromplant := plant;
         toplant   := plant;


     DATA
         Price[product]                := (120.00, 100.00, 115.00);
         Demand[plant, product, month] := DATAFILE("Demand6.dat");
         ProdCost[plant, product]      := DATAFILE("ProdCost.dat");
         ProdRate[plant, product]      := DATAFILE("ProdRate.dat");
         ProdDaysAvail[month]          := (23, 20, 23, 22);
         InvtCost[plant, product]      := DATAFILE("InvtCost.dat");

         InvtCapacity[plant]           := (800, 400, 500, 400);
         ShipCost[fromplant, toplant]  := DATAFILE ("ShipCost.dat");

     VARIABLES
         Produce[plant, product,month]      -> Prod;
         Inventory[plant, product, month]   -> Invt;
         Sales[plant,product, month]        -> Sale;
         Ship[product, month, fromplant, toplant]
             WHERE (fromplant <> toplant);

     MACROS
         TotalRevenue  := SUM(plant, product,month: Price * Sales);
         TotalProdCost := SUM(plant, product, month: ProdCost* Produce);
         TotalInvtCost := SUM(plant, product, month: InvtCost * Inventory);
         TotalShipCost := SUM(product, month, fromplant,toplant: ShipCost * Ship);
         TotalCost     := TotalProdCost + TotalInvtCost + TotalShipCost;

     MODEL

         MAX Profit= TotalRevenue - TotalCost;

     SUBJECT TO
         ProdCapacity[plant, month] ->PCap:
             SUM(product: Produce / ProdRate)  <=  ProdDaysAvail;

         PlantBal[plant, product, month] -> PBal:
               Produce + Inventory[month-1]
             + SUM(fromplant:Ship[fromplant, toplant:=plant])
            =
               Sales + Inventory
             + SUM(toplant: Ship[fromplant:=plant,toplant]);

         MaxInventory[plant, month] -> MaxI:
             SUM(product: Inventory)  <=  InvtCapacity;

     BOUNDS
         Sales < Demand ;

     END
    

Introdurre Nuovi Elementi al Modello Passo per Passo

Passo1: Eseguire MPL e Creare un Nuovo Modello

  1. Eseguire l'applicazione MPL.

  2. Scegliere File (Archivio)| Open (Aprire) e aprire il modello dalla sessione precedente Planning5.mpl.

  3. Scegliere File (Archivio)| Save As (Salvare come) per salvare il nuovo file di modello Planning6.mpl.

Passo 2: Cambiare il Titolo al Modello

Cambiare il Titolo al Modello per sottolineare che state lavorando con il modello Planning6:

     TITLE
        Production_Planning6;
    

Passo 3: Aggiungere Indici Fittizi al Modello per gli Impianti di Partenza e di Destinazione

In questa sessione, state per aumentare il modello per permettere spedizioni tra gli impianti. Gli Indici Fittizi sono utili quando dovete definire un vettore, che si riferisce allo stesso indice più di una volta, come sottoscritto. Gli indici fittizi sono una copia esatta dell'indice precedentemente definito.

In questo caso, state creando una variabile di vvettore che rappresenti quanto trasportare tra gli impianti. Questo significa che avete bisogno di due indici fittizi per rappresentare gli impianti di partenza e di destinazione. Aggiungere le seguenti definizioni per i due nuovi indici fittizi che chiamerete fromplant e toplant alla fine della sessione INDEX:

      INDEX
         product      := (A1, A2, A3);
         month        := (Jan, Feb, Mar, Apr);
         plant        := (p1, p2,p3, p4);
         fromplant    := plant;
         toplant      := plant;
    

Passo 4: Aggiornare il Vettore di Dati 'Demand' per includere l'indice 'Plant':

Abbiamo ora una differente richiesta per ogni impianto. La definizione per il vettore di dati Demand necessita di essere aggiornata così da includere l'indice plant. Nell'editor del modello, aggiungere l'indice plant al vettore di dati Demand e cambiare il nome del file in Demand6.dat.

     DATA
        Price[product]                := (120.00, 100.00, 115.00);
        Demand[plant, product, month] := DATAFILE("Demand6.dat");
    

Dato che il vettore Demand ora ha tre indici, il file di dati per esso necessita di essere aggiornato. Quindi, create un nuovo file di dati chiamato 'Demand6.dat' usando i valori di dati dalla tabella nella descrizione del problema forniti, prima, in questa sessione. Introdurre i valori di dati nel file di dati come segue:

     !
     ! Demand6.dat - Demand for each product and each plant
     !
     ! Demand[plant,product,month]:
     !
     !           Jan    Feb    Mar    Apr
     !          ---------------------------
     !plant 1:
                 4300,  4200,  6400,  5300,
                 4500,  5400,  6500,  7200,
                 5400,  6700,  7800,  8200,
     !plant 2:
                 5100,  6200,  5400,  7600,
                 6300,  7100,  5200,  6300,
                 4800,  6500,  5000,  7200,
     !plant 3:
                 4100,  6100,  4700,  5800,
                 5300,  5200,  5700,  4100,
                 4200,  4100,  5200,  6300,
     !plant 4:
                 4300,  4100,  5300,  4500,
                 5300,  6400,  4200,  6200,
                 5600,  5200,  3800,  4100
    

Quando avete dati a tre dimansioni nei files, elencate i loro valori nello stesso ordine in cui sono stati definiti gli indici nel vettore di dati per il modello. Per esempio, nel sovrastante file di dati Demand6, l'indice più a sinistra è l'indice plant, seguito dall'indice producte dall'indice month.

Passo 5: Aggiornare il Vettore di Dati 'InvtCost' e la Costante di Dati 'InvtCapacity' per includere l'Indice 'plant'

Dato che, ora, potete immagazzinare l'inventario ad ogni impianto, avete bisogno di aggiornare il costo dell'inventario e i dati di capienza dell'inventario per includere l'indice plant. Nell'editor del modello, aggiungere l'indice plant alla dichiarazione del vettore di dati InvtCost e alla costante di dati InvtCapacity. Poi, per il vettore di dati InvtCost rimuovere la lista di numeri e rimetterla con la parola chiave DATAFILE e con il nome del file 'InvtCost.dat.' Per la InvtCapacity togliere il valore singolo 800 e rimetterlo con la list di quattro valori, uno per ogni impianto, presi dalla descrizione del problema precedentemante in questa sessione.

     InvtCost[plant, product] := DATAFILE("InvtCost.dat");
     InvtCapacity[plant]      := (800, 400, 500, 400);
    

In seguito, dovete creare un nuovo file di dati chiamato 'InvtCost.dat' usando i valori del costo dalla tabella del cost dell'inventario nella descrizione del problema. Introdurre i valori dei dati nel file di dati come segue:

      !
      ! InvtCost.dat - Inventory cost per item a month
      !
      ! InvtCost[plant,product]:
      !
      !         A1    A2    A3
      !     -----------------------
               8.50,  7.00, 6.50
               9.80,  9.80, 9.80
               7.50,  7.50, 7.50
               9.30,  8.00, 6.50
     

Passo 6: Aggiungere un Vettore di Dati per i Costi di Trasporto

Ci sono certi costi coinvolti nel trasporto dei prodotti tra impianti. Nell'editor del modello, aggiungere un nuovo vettore di dati chiamato ShipCost definito su i due indici fittizi fromplant e toplant segiuto dalla parola chiave DATAFILE e dal nome del file ShipCost.dat.

     ShipCost[fromplant, toplant] := DATAFILE("ShipCost.dat");
    

Successivamente dovete creare un nuovo file di dati chiamato ShipCost.dat che contenga le figure di costo per il trasporto tra impianti fornite nella descrizione del problema. Introdurre i valori dei dati per il file di dati come segue:

     !
     ! ShipCost.dat - Shipping costs from plant to plant
     !
     ! ShipCost[fromplant, toplant]
     !
                0, 15.00, 21.00, 13.00,
            16.00,     0, 12.00, 12.00,
            14.00, 17.00,     0, 15.00,
            21.00, 13.00, 10.00,     0,
    

Passo 7: Aggiungere un Vettore di Variabile per il Trasporto tra Impianti.

Stiamo rendendo possibile il trasporto tra impianti, perciò, si deve creare una nuova variabille che decida quanto deve essere trasportato di ogni prodotto al mese. Questo vettore di variabile sarà definito sugli indici fittizi fromplant e toplant come gli indici product e month. Aggiungere la seguente definizione per il vettore di variabile Ship alla sezione VARIABLES:

     Ship[product, month, fromplant, toplant]
        WHERE (fromplant <> toplant);
    

Dato che non vogliamo trasportare un prodotto da un impianto all'impianto stesso, usiamo la condizione WHERE per rimuovere tutti gli elementi di vettore in cui l'impianto di partenza è lo stesso di quello di destinazione.

Passo8: Aggiungere il Costo Totale di Trasporto alla funzione obiettiva

Nella sezione MACROS aggiungere una nuova definizione macro per il costo totale del trasporto chiamata TotalShipCost e aggiorniamo la macro TotalCost per includere la nuova macro come segue:

      TotalShipCost := SUM(product, month, fromplant, toplant: ShipCost * Ship);
      TotalCost     := TotalProdCost + TotalInvtCost + TotalShipCost;
    

Si noti che l'attuale definizione della funzione obiettivo non ha bisogno di essere cambiata in quanto la macro TotalCost contiene tutti i cambiamenti.

Passo 9: Aggiornare il vincolo d'Equilibrio dell'Inventario in un vincolo d'Equilibrio d'Impianto aggiungendo la Variabile 'Ship'

Dato che ora abbiamo permesso trasporti tra impianti, si deve aggiornare il vincolo d'equilibrio dell'inventario dal modello precedente ad un vincolo d'equilibrio d'impianto. Come prima cosa, cambiare il nome del vincolo da InvtBala PlantBal e aggiungere l'indice plant alla dichiarazione. Di seguito, dato che il vincolo, ora, è dichiarato, non dobbiamo più sommare l'indice plant per la variabile Produce.

     PlantBal[plant, product, month] -> PBal:

               Produce + Inventory[month-1]
             + SUM (fromplant:Ship[fromplant, toplant:=plant])
           =
               Sales + Inventory
             + SUM(toplant: Ship[fromplant:=plant, toplant]);
    

Sul lato sinistro, dove abbiamo portato tutto quello che sta andando verso l'impianto, aggiungere una sommatoria per sommare tutti i trasporti da ognuno degli altri impianti all'attuale impianto per il vincolo. Nella sommatoria, introdurre la variabile Ship con l'impianto di destinazione prendendo i valori dall'attuale indice plant.

Sul lato destro, dove abbiamo portato tutto quello che esce dall'impianto, aggiungere un'altra sommatoria per sommare insieme tutti i carichi dall'impianto attuale ad ognuno degli altri impianti. Nella sommatoria introdurre la variabile Ship questa volta con l'impianto di partenza prendendo il valore dell'attuale indice plant per il vincolo.


Risolvere il Modello e Analizzare la Soluzione

Il prossimo passo sarà risolvere il modello Planning6 scegliendo Solve CPLEX dal menu Run. Se tutto procede bene MPL visualizzerà il messaggio "Optimal Solution Found" "Trovata Soluzione Ottimale". Se c'è una finestra d'errore di messaggio con un errore di sintassi per favore, si controlli e si confronti la formulazione introdotta con il modello dettagliato precedentemente in questa sessione.

Userete la finestra di definizioni del modello ancora come nella Sessione5 per guardare le parti della soluzione che c'interessano. per aprire la finestra di definizioni del modello per il modello Planning6 scegliere Model Definitions dal menu View.

Definizioni del Modello attraverso Finestra ad Albero per il modello Planning6

Per guardare i valori della variabile Produce, si clicchi due volte sull' articolo Produce nell'albero, o si selezioni lo stesso e poi si prema il bottone View. Questo visualizzerà una finestra contenente solo i valori per la variabile Produce come mostrato di sotto.

     VARIABLE Produce[plant,product,month] :

        plant  product  month           Activity     Reduced Cost
       -----------------------------------------------------------
        p1     A1       Jan              4300.0              0.0
        p1     A1       Feb              4200.0              0.0
        p1     A1       Mar              6400.0              0.0
        p1     A1       Apr              5300.0              0.0
        p1     A2       Jan              1080.0              0.0
        p1     A3       Jan              5400.0              0.0
        p1     A3       Feb              5220.0              0.0
        p1     A3       Mar              4590.0              0.0
        p1     A3       Apr              5130.0              0.0
        p2     A1       Jan              5100.0              0.0
        p2     A1       Feb              6200.0              0.0
        p2     A1       Mar              5400.0              0.0
        p2     A1       Apr              7600.0              0.0
        p2     A2       Jan              6177.3              0.0
        p2     A2       Feb              3927.3              0.0
        p2     A2       Mar              5931.8              0.0
        p2     A2       Apr              3681.8              0.0
        p3     A1       Jan              4100.0              0.0
        p3     A1       Feb              6100.0              0.0
        p3     A1       Mar              4700.0              0.0
        p3     A1       Apr              5800.0              0.0
        p3     A3       Jan              4166.7              0.0
        p3     A3       Feb              1933.3              0.0
        p3     A3       Mar              3766.7              0.0
        p3     A3       Apr              2733.3              0.0
        p4     A1       Jan              3850.0              0.0
        p4     A1       Feb              2828.6              0.0
        p4     A1       Mar              5300.0              0.0
        p4     A1       Apr              4500.0              0.0
        p4     A3       Jan              5600.0              0.0
        p4     A3       Feb              5200.0              0.0
        p4     A3       Mar              4677.3              0.0
        p4     A3       Apr              4836.4              0.0
       -----------------------------------------------------------
    

Come potete vedere, la produzione è ora distribuita tra differenti impianti in un modo più redditizio. Alcuni prodotti sono chiaramente prodotti meglio in alcuni impainti dovendo considerare il costo di produzione e il costo di trasporto. Per esempio, il prodotto A2 è prodotto negli impianti p1 e p2, ma non in p3 e p4, mentre il prodotto A3 è prodotto negli impianti p1, p3 e p4. Il prodotto A1 è prodotto nella maniera più economica in tutti gli impianti.

Se si va ancora nelle tre finestre e si apre una finestra per la variabile Ship si avranno i seguenti valori di soluzione:

     VARIABLE Ship[product,month,fromplant,toplant] :

        product  month  fromplant  toplant           Activity     Reduced Cost
       ------------------------------------------------------------------------
        A2       Mar    p2         p4                  331.8              0.0
        A3       Mar    p4         p3                  877.3              0.0
        A3       Apr    p4         p3                  736.4              0.0
       ------------------------------------------------------------------------
    

Come potete vedere il modello suggerisce che si trasporti il prodotto A2 dall'impianto p2 all'impianto p4. Allo stesso modo, il prodotto A3 è trasportato dall'impianto p4 e p3. Chiaramente, gli impianti p2 e p4 hanno capacità extra a un costo più basso che può essere usato per produrre beni che gli impianti p4 e p3 necessitano.


Back To Top | Maximal Home Page | Overview | Previous Page | Next Page